package demo1;

import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Annotated;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //需求:实例化一个User并调用它的sayHello方法
        //调用方:Demo类     被调用方法:User类


        /*
            调用方控制着被调用方的创建:
            我们是在Demo类中明确的编码实例化被调用方User
            优点:简单明了
            缺点:代码写死了，一旦被调用方因为需求而变化，调用方这边要跟着修改代码
                比如后期不需要调用User，改为调用Person
         */
        //正常编码
        User user = new User();
        user.sayHello();


        /*
            为了应对被调用方的变化尽可能不更改调用方法，我们引入反射机制

            优点:灵活，不会因为被调用方法的改变而修改调用方代码
            缺点:要编写大量的反射代码
            实际开发中我们存在大量的调用方与被调用方的关系，都要在调用方引入反射机制，重用差
            除非编写可以复用的反射代码--最终发现如果你成功了，你写了个Spring框架
         */
        Class cls = Class.forName("demo1.User");
        User user1 = (User)cls.newInstance();
        user1.sayHello();

        /**
         * 使用Spring容器
         * 优点：不再需要编写大量的反射代码
         *      Spring容器可以进行复杂的对象初始化，后期还可以利用AOP额外添加业务。
         * 缺点:几乎没有什么缺点，轻微侵入性。
         */
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext("demo1");
        User user2 = context.getBean(User.class);
        user2.sayHello();

    }
}
